import tkinter
import tkinter.filedialog
from tkinter import ttk
import pandas as pd
import subprocess
import glob
import os
import re
import time
import numpy as np

top = tkinter.Tk()
top.title('check lab data v1.0.0')
screenwidth = top.winfo_screenwidth()  # 屏幕宽度
screenheight = top.winfo_screenheight()  # 屏幕高度
width = 800
height = 480
x = int((screenwidth - width) / 2)
y = int((screenheight - height) / 2)
top.geometry('{}x{}+{}+{}'.format(width, height, x, y))  # 大小以及位置


# top.iconbitmap("icon.ico")

def choose_fiel():
    selectFileName = tkinter.filedialog.askopenfilename(title='选择文件')  # 选择文件
    e.set(selectFileName)


e = tkinter.StringVar()
e_entry = tkinter.Entry(top, width=80, textvariable=e, borderwidth=3, foreground='#3FBF3F')
e_entry.pack()

# tree = ttk.Treeview(top,height=10,width=80)  # 表格
tree = ttk.Treeview(top, selectmode="extended", height=10, show='headings')
tree["columns"] = ("A")
tree.heading("A", text="消息提示")
tree.column("A", minwidth=0, width=180)
tree.pack(pady=20, fill="both", expand=True)


def upload_func(INFO_FILE):
    return_true = True
    error_log = []
    warening_log = []
    '''
        检查数据
    '''
    # LANE_DIR_NUMBER = 0  #TODO 文本输入 lan的数量 用于校验表的sheet数量
    # input_total_sample_number = 9 #TODO 文本输入总的样本数量
    chip_name = []  # 用于存放excel表格中的芯片号，
    sheet_number = 0
    lane_number = 0
    file_chip_name = ""  # 芯片编号
    new_info = pd.DataFrame()

    raw_info = pd.read_excel(INFO_FILE, sheet_name=None, dtype=str)
    base_name = os.path.basename(INFO_FILE)
    if base_name.startswith('FCS'):
        lane_number = 2
    elif base_name.startswith('FCL'):
        lane_number = 4
    base_name_list = base_name.split("-")
    if len(base_name_list) != 4:
        error_log.append(f"错误号:101,错误内容：输入文件名称错误，请检查！！！")
    else:
        file_chip_name = base_name_list[2]  # 芯片编号
    # merge sheets
    for sheet in raw_info.keys():
        if not raw_info[sheet].empty:
            tmp = raw_info[sheet]
            NOT_ALLOWED_SHEET = "^L0[1234]"
            if not re.compile(NOT_ALLOWED_SHEET).findall(sheet):
                error_log.append(f"错误号:102,错误内容：Lan名称 {sheet} 命名错误，请检查！！！")
            tmp["LANE"] = sheet
            sheet_number += 1
            new_info = pd.concat([new_info, tmp])
        else:
            pass
    new_info = pd.DataFrame(new_info[["芯片编号", "样本编号", "序列号", "LANE"]])
    new_info = new_info.dropna(axis=0, subset=["样本编号", "序列号"])
    chip_name = new_info["芯片编号"].dropna().tolist()
    new_info = new_info.applymap(lambda x: "".join(str(x).replace(" ", "")))

    # need the same chip name in every sheet
    if len(set(chip_name)) != 1:
        error_log.append(f"错误号:103,错误内容：More than one chip name in {base_name}!!! Please check!!!")
    else:
        sample_name = new_info["样本编号"].dropna().tolist()
        # check chip name, lane number, error sample
        # if sheet_number != lane_number or sheet_number != LANE_DIR_NUMBER or lane_number != LANE_DIR_NUMBER:
        if sheet_number != lane_number:
            error_log.append(f"错误号:104,错误内容：表格LANE数量与实际数量不一致!!!")
        if file_chip_name != chip_name[0]:
            error_log.append(f"错误号:105,错误内容：文件名的芯片编号{file_chip_name}和表格中的芯片编号{chip_name}不一致!!!")
        # check error sample, type: duplicate sample in one lane
        total_sample_number = len(set(sample_name))
        # if total_sample_number > 0:
        #    error_log.append(f"提示号：301,表格样本数量与输入的样本数量不一致!!!,表格中有{total_sample_number}个样本")
        duplicate_df = new_info.groupby(["样本编号", "LANE"]).filter(lambda x: len(x) > 1)
        duplicate_error_sample = duplicate_df.loc[:, "样本编号"].tolist()
        new_info = pd.concat([new_info, duplicate_df]).drop_duplicates(keep=False)
        # if len(set(duplicate_error_sample)) > 0:
        #     error_log.append(
        #         f"错误号:106,Duplicate sample name in one lane!!! Please check {duplicate_error_sample} in table!!!")
        # check error sample, type: wrong name format
        for sample in sample_name:
            name_error_sample = []
            NOT_ALLOWED_STR = "~!@#$%^&*()_+-*/<>,.[]\/"
            special_str = []
            for i in NOT_ALLOWED_STR:
                if i in str(sample):
                    name_error_sample.append(str(sample))
                    special_str.append(i)
                else:
                    pass
            if len(name_error_sample) != 0:
                error_log.append(
                    f"错误号:106,错误内容：Looks like {name_error_sample} in table has special character'{special_str}', please check!!!")
            else:
                pass
        # get sample-barcode relationship, do merge or rename
        MERGE_LIST = []
        for i in set(sample_name):
            ret = sample_name.count(i)  # searching sample needed to merge
            if ret > 1:
                MERGE_SAMPLE_BARCODE = new_info.loc[new_info["样本编号"] == i, "序列号"].tolist()
                MERGE_LANE = new_info.loc[new_info["样本编号"] == i, "LANE"].tolist()
                MERGE_SAMPLE = f"{i}:{MERGE_LANE}:{MERGE_SAMPLE_BARCODE}"
                MERGE_LIST.append(MERGE_SAMPLE)
                MERGE_LIST = [my.replace('\'', '').replace(' ', '').replace('[', '').replace(']', '') for my in
                              MERGE_LIST]
            else:
                pass
        MERGE_SAMPLE_NUMBER = 0
        if len(MERGE_LIST) != 0:
            warening_log.append(
                f"警告号：201,错误内容：样本名称重复 {MERGE_LIST}, please check!!!")

    if len(error_log) > 0:
        return_true = False

    '''
        上传数据
    '''
    if return_true:
        tree["columns"] = ("A", "B", "C", "D","E")
        tree.column("A", width=50, anchor="center")  # 表示列,不显示
        tree.column("B", width=200, anchor="center")
        tree.column("C", width=200, anchor="center")
        tree.column("D", width=50, anchor="center")
        tree.column("E", width=200, anchor="center")

        tree.heading("A", text="序号")  # 显示表头
        tree.heading("B", text="芯片编号")
        tree.heading("C", text="样本编号")
        tree.heading("D", text="序列号")
        tree.heading("E", text="LANE")
        tree.insert("", 0, text="index", values=("", "检验通过", "检验通过","检验通过", "检验通过"))  # 插入数据，
        for index, row in new_info.iterrows():
            tree.insert("", index+1, text="index", values=(index+1,row["芯片编号"], row["样本编号"], row["序列号"], row["LANE"]))  # 插入数据，


    else:
        tree["columns"] = ("A")
        tree.column("A", minwidth=0, width=800)  # 表示列,不显示
        tree.heading("A", text="提示内容")
        for index, value in enumerate(error_log):
            tree.insert("", index, text=index, values=(value,))

submit_button = tkinter.Button(top, text="选择文件", command=choose_fiel)
submit_button.pack()
submit_button = tkinter.Button(top, text="检查并上传", command=lambda: upload_func(e_entry.get()))
submit_button.pack()

top.mainloop()
